Reply to this topicStart new topic
> GetStat, SetStat, ModStat, I want to know exectly how they behave
Björn
post Sep 15 2005, 07:33 AM
Post #1


Curate
*

Joined: 22-December 04
From: Stockholm, Sweden



Okay, so I've been reading a few threads about this (and Galsiah posted in all of them tongue.gif). I know there obviously are some problems with these funktions, I just don't know exactly which they are. We can begin with GetStat, will it show the stat including a bonus/penalty or without (my guess is including)?
Then SetStat, Will this set the base stat to the value, or the stat including a bonus/penalty (my guess is the latest one)? If the first is true, what will happen when the bonus/penalty is no longer there? And does SetStat take variables?
And last, ModStat. Will that set the base stat to the value + the latest value, or including bonus/penalty? Same question as above here, what will happen when the spell wears off? It stops at 100, right? Does this take variables? I've also heard that if you "ModStat 1" one step at a time, you will go above 100 till you reach 100 plus your bonus. I guess that's true then, but what if you have a penalty, will it stop before 100 then?

As you can see, I want to know pretty much everything about these functions. So just answer all the questions you know about, if any.

Thanks a lot!


--------------------
aka Burning Thunder
--------------------
Rel: Combat Detector
The only way to reliably detect combat in MW without a script extender.

Beta: Advanced Lockpicking
TopReport Post
User is offlinePM
+Quote Post
Niddler
post Sep 15 2005, 09:26 AM
Post #2


Adept


Joined: 15-February 05



I'll test this, if you give me a few minutes to make the script and do the work. Although my guess is that modstat and setstat only effect the max 100 base stat.

Confirmed, get___ - such as getStrength includes the modifiers that go above 100. When I wear my cool gloves, it returns 120. When I take them off it returns 100.

Confirmed, set___ - such as setStrength will only set your base stats up to 100 and no further (at least without further action).

Confirmed, mod___ - such as modStrength will only set your base stats as high as 100 and no further (perhaps you can change the maximum lvls?)

This post has been edited by Niddler: Sep 15 2005, 09:49 AM
TopReport Post
User is offlinePMEmail Poster
+Quote Post
Spectre5
post Sep 15 2005, 11:49 AM
Post #3


Initiate


Joined: 2-January 05



Get[Stat] returns the current value of [stat]. This includes any bounuses/penalties.

Set[Stat], [value] sets base[stat] to [value]. [value] can be any number >= 0. I've never tried to pass a negitive number, but I assume it won't work.
EDIT: negative values may work. If you drain a skill more than your skill (i.e. your LongBlade is 30, and you have a drain LongBlade 35 pts. effect,) the menu shows the skill as 0, but you need to train the skill several times before it starts to in crease.

Mod[Stat], [value] increases [stat] by [value]. [value] can be negative. ModStat cannot increses a stat above 100, this is hard-coded and cannot be changed. I'm not sure if there's a lower limit.



This post has been edited by Spectre5: Sep 15 2005, 11:53 AM
TopReport Post
User is offlinePM
+Quote Post
Galsiah
post Sep 15 2005, 12:57 PM
Post #4


Disciple
**

Joined: 8-January 05
From: UK



QUOTE(Björn @ Sep 14 2005, 10:33 PM)
(and Galsiah posted in all of them tongue.gif).
*

Good to know I'm not missing any smile.gif

Here's most of what you need to know:

GetStat, ModStat and SetStat: A concerned modder’s guide.
Throughout the term “base stat” means the value of the stat when yellow – i.e. unmodified by any in game bonus / penalty apart from fortification abilities.

GetStat:
Always returns the current stat – including any bonus / penalty. No nasty side effects as far as I’m aware, so GetStating should always be safe. There is (sadly) no GetBaseStat function. MWSE has these I think, but they don't include e.g. racial fortification abilities in the base (I think), and usually you'd want them included.
Note that all stats are stored as floats, even though they should nearly always be integers. Usually this makes no difference.

Most of the problems of ModStat and SetStat explained below are only really important for the player (and companions I guess). These functions won’t do anything worse than screwing up the stats they operate on, so for normal NPCs, there’s not much point worrying about all this. I’ve only tested the following on the player, but I presume the same is true for NPCs.

As with pretty much anything in Morrowind modding, if you have a choice to use scripting or something else, then use something else. For ModStat / SetStat, the “something else” will usually be fortify/drain stat spell effects or curses. For most purposes, standard effects will work as well as ModStat and SetStat, and will be much less buggy.

ModStat:

Usually increases (or decreases) the stat concerned by the amount given (local variables are accepted). Both the current stat and the base stat are affected. Usually preserves the amount of fortification or damage on the stat.

E.g. for a player with strength 50(base) + 10(fortification) = 60(current)
Player->ModStrength 10 will give 60(b.) + 10(f.) = 70(c.), just as you’d expect.

Limitations: ModStat can never decrease a stat below zero. It also cannot increase a base stat to a value over 100. Trying to Modstat below zero or above 100 can cause trouble in the following ways:

Strength = 30(b.) + 0(f.) = 30(c.)
ModStrength, -50 gives
Strength = 0(b.) + 0(f.) = 0(c.)
ModStrength 50 [hoping to undo the first modstrength]
Strength = 50(b.) + 0(f.) = 50(c.) – and the player has a permanent bonus.

You can try to avoid this by instead checking that you don’t reduce the stat by more than the current value, but that won’t always work. For example:
Strength = 40(b.) + 10(f.) = 50(c.)
ModStrength -50
Strength = 0(b.) + 0(f.) = 0(c.)
ModStrength 50
Strength = 50(b.) + 0(f.) = 50(c.) – and the player’s base strength is increased.
If he then removes the fortification, his strength will show up as damaged. Restoring and replacing the forification will leave him with:
Strength = 50(b.) + 10(f.) = 60(c.)

It’s never safe to ModStat down by more than the player’s base stat. Given that there’s no failsafe method to determine the player’s base stat, this is annoying [the only ways I know to determine the player’s base stat are the method which I use in GCD – complicated, and doesn’t work correctly when the player’s stat is damaged -, using MWSE, which I think doesn’t include permanent abilities in the base (for most purposes you’d want permanent abilities to count towards the base). Even systematically removing every conceivable bonus / penalty – which is a drag anyway – won’t always work with other scripted mods].

Going over 100 has similar problems. The following is fine:
Strength = 70(b.) + 20(f.) = 90(c.)
ModStrength, 20 gives
Strength = 90(b.) + 20(f.) = 110(c.)
ModStrength -20 gives
Strength = 70(b.) + 20(f.) = 90(c.) – all fine.

However, this also happens for some reason:
Strength = 70(b.) + 20(f.) = 90(c.)
ModStrength, 50 gives
Strength = 100(b.) + 40(f.) = 140(c.) – already screwed up.
ModStrength -50 gives
Strength = 50(b.) + 40(f.) = 90(c.) – further screwed up.

This problem arises because if a stat is fortified or damaged, and the base is not 100, ModStat always increases the current stat by the value you give it, even if the base stops at 100. If the base is 100, ModStating won't have any effect. If the stat is equal to its base value, ModStat will behave normally.

So this is fine (so long as you don’t ModStat -50 afterwards):
Strength = 70(b.) + 0(f.) = 70(c.)
ModStrength, 50 gives
Strength = 100(b.) + 0(f.) = 100(c.)

And this is fine:
Strength = 100(b.) + 20(f.) = 120(c.)
ModStrength, 50 gives
Strength = 100(b.) + 20(f.) = 120(c.)

But this isn’t:
Strength = 99(b.) + 20(f.) = 119(c.)
ModStrength, 50 gives
Strength = 100(b.) + 69(f.) = 169(c.) – oh dear.

Of course as a modder you won’t know in general what the Base + Fortification is before you use the ModStat function, so you have no way to compensate for errors even once you know what can go wrong. Joy!

Ok, so as long as you never try to ModStat the current stat over 100, everything should be fine, right?
Sadly not:
Strength = 95(b.) - 10(damage) = 85(c.)
ModStrength, 15 gives
Strength = 100(b.) + 0(f.) = 100(c.) – OK so far
ModStrength, -15 gives
Strength = 85(b.) + 0(f.) = 85(c.) – Permanent strength damage.

So under what circumstances will ModStating up or down give reliably predictable results?
Only when you know the base value of the stat.

Can you reliably work out the base value of the stat?
No – only in some situations is it possible (the process is explained below, and implemented in my Gals_Sk_Acrobatics script in GCD). Even then it’s not easy. (it’s worth checking script extenders for updates though)


SetStat:
Sets both the base and the current value to the value you give it (also accepts local variables). Can set base and current to values over 100. Accepts negative values, which can be useful in conjunction with ModStat (see below).

This will pretty much always cause problems if the player’s current stat is not equal to their base stat. If their stat is fortified, and you SetStat it, it’ll turn yellow at the value you give it. Removing the fortification, then restoring will give the player a permanent bonus.
If their stat is damaged, SetStating it will again turn it yellow, but this time at a lower value than you (probably) intended. They will instantly have their base knocked down to the value you set.

Using SetStat is therefore never even slightly safe unless you know the player’s base stat, and compensate accordingly. While you can’t guarantee that ModStat won’t cause trouble, you can almost guarantee that SetStat will.
Using SetStat is therefore almost always a bad decision – if you’re ever not sure whether it’s a bad decision, then it is.


Then are these functions useless!?
Not always. You can use them on NPCs without worrying too much. Using them on companions could occasionally not have the effect you want, but it’s unlikely the player would notice.

Using ModStat on the player can be safe, so long as you’re careful – e.g. to increase strength by (up to) 10 points temporarily, you could:
Give the player a very strong restore strength curse for a frame or two. (you can then be sure his strength isn’t damaged)
ModStrength by MIN{ 10, 100-current }

ModStrength down by the same amount when you want the effect to finish.

You can never be sure that giving a temporary penalty won’t cause trouble, but if you only reduce the stat by at most 30, then it’ll usually be fine since most players start with all stats that high. Restoring the stat after you’ve reduced it like this could cause trouble if the player has since gained base stat points, and his stat started close to 100.


Some "cunning" tricks with SetStat / ModStat:

WARNING – using the following tricks might cause even more trouble than using the functions normally. Use with care. Conflicts are likely.

Finding the base of a stat:
You can find the base of a stat using the (mis)behaviour of ModStat, as follows:
(1)Make sure that the player’s stat isn’t damaged [You have been tracking increases in the natural values of the stat since the beginning of the game, haven’t you? If you haven’t, then you have no way of knowing if it’s damaged – you could check the base value on installation of your mod, so long as you ask the player to install when stats aren’t damaged / fortified].
(2)If it is damaged, give up. (you might want to check script extenders)
(3)If it isn’t:
(4)Store the current value of the stat.
(5)Mod the stat up to 100 if it isn’t already 100 or more.
(6)ModStat, 1 as many times as you can while the stat still increases.
(7)The fortified part of the stat is the value it reached minus 100.
(8)The base part of the stat is the current value minus the fortified part.
(9)Return the stat to its current value (DON’T use SetStat, use ModStat).

Armed with the base value, you can now use ModStat and SetStat wisely and safely, so long as you’re very careful.


Damaging a stat:
To set a stat to e.g. 50 damaged from 70, you can do the following:
Player->SetStat, -20 [Base and current are now both -20]
Player->ModStat, 0 [Necessary: sets the base to 0]
Player->ModStat, 70 [Base = 70, current = 50 (red)]

This level of precision is not possible in general using e.g. damage stat curse effects, but it’s not usually necessary either. The above can also be done within one frame, whereas a curse effect might take a second to kick in. Again, the speed can be useful, but is usually unnecessary.

Fortifying a stat:
To set a stat to e.g. 120 fortified from 90, you can do the following:
Player->SetStat 130 [Base and current are now both 130]
Player->ModStat, 0 [Necessary: sets the base to 100]
Player->ModStat, -10 [Base = 90, current = 120 (white)]


Right, I hope that made some sense. Now you know pretty much everything about the Get/Set/ModStat functions. Just remember not to use them wink.gif.

This post has been edited by Galsiah: Sep 15 2005, 11:35 PM


--------------------
Galsiah's Character Development
Lasting character diversity. Seamless, limitless, balanced progression.
GCD thread

Dynamic Pool
Silliness & physics.
TopReport Post
User is offlinePMEmail Poster
+Quote Post
Björn
post Sep 15 2005, 06:41 PM
Post #5


Curate
*

Joined: 22-December 04
From: Stockholm, Sweden



Thank you, Galsiah! That's a Very good explenation. Just a few more questions:
QUOTE
(2)If it is damaged, give up. (you might want to check script extenders)

Can't you use a restore stat curse here?

Well that was just one question, but I'll come with more if can think of anything. But thanks!


--------------------
aka Burning Thunder
--------------------
Rel: Combat Detector
The only way to reliably detect combat in MW without a script extender.

Beta: Advanced Lockpicking
TopReport Post
User is offlinePM
+Quote Post
Galsiah
post Sep 15 2005, 11:17 PM
Post #6


Disciple
**

Joined: 8-January 05
From: UK



Yes, you could - but you might not want to restore the player's stat when you test the base. Also, restoring the stat means you need to wait about a second for the curse to start taking effect, so you can't check the base within one frame.

If you don't mind it taking a second or so to check, then you could keep the stat damaged like this:
(1) Store the value of the player's current stat. (call it InitialStat)
(2) Add a very strong restore stat curse.
(2b)[You might want to keep updating InitialStat until the curse starts]
(3) Check that the curse is affecting the player.
(4) Wait a fraction of a second (outside menumode).

The stat should now not be damaged, so do the base checking:
(5)Mod the stat up to 100 if it isn’t already 100 or more.
(6)ModStat, 1 as many times as you can while the stat still increases.
(7)The fortified part of the stat is the value it reached minus 100.
(8)The base part of the stat is the current value minus the fortified part.

You've found the base, so now you need to return the stat to its initial state:
(10)If Base <= InitialStat, then ModStat by [Base - 100]
(11)If Base > InitialStat, SetStat to [InitialStat - Base], ModStat 0, ModStat Base.

Doing (2b) allows the player to have the stat changed during the gap between the curse being added, and it affecting the player (about 1 second in my experience). Things could still go a bit wrong if the player's stat is altered by something else within (4): the base will be found correctly, but the player might lose whatever bonus/penalty was applied when the stat is returned to InitialStat in (10) / (11). This isn't a big problem, since (4) only needs to take a few frames.


--------------------
Galsiah's Character Development
Lasting character diversity. Seamless, limitless, balanced progression.
GCD thread

Dynamic Pool
Silliness & physics.
TopReport Post
User is offlinePMEmail Poster
+Quote Post

Fast ReplyReply to this topicStart new topic

 



Lo-Fi Version 0.0723 sec    0.57    8 queries    GZIP Enabled
Time is now: 17th July 2006 - 04:21 PM